ESP32 单片机学习笔记 |
您所在的位置:网站首页 › esp32 网速 › ESP32 单片机学习笔记 |
ESP32 单片机学习笔记 - 06 - (以太网)Ethernet转Wifi
暂停了半个多月的学习,去调车了。现在课设开始了,赶紧回来把一开始的“以太网”目标学完。但是却发现,好像和自己的理解不太一样。 文章目录 ESP32 单片机学习笔记 - 06 - (以太网)Ethernet转Wifi一、以太网基本示例 - Ethernet1.确定方案2.准备工作3. 例程解析 二、以太网 到 Wi-Fi AP"路由器"1. 例程解析 三、以太网 编程指南1. 基本以太网概念2. 配置 MAC 和 PHY3. 创建MAC和物理实例4. 安装驱动程序5. 将驱动程序连接到 TCP/IP 堆栈6. 以太网驱动程序的误控7. 流控制 四、总结 一、以太网基本示例 - Ethernet编程指南:以太网,啥介绍都没有,我傻了。我把例程都做完后还是清楚怎么用以太网,就发觉自己是不是理解错了,学习方向/顺序是不是错了。 官方例程:ethernet/basic,这个例程只有以太网连接功能。 编程指南(英文):Ethernet,惊呆了,原来所有内容都在英文版,中文版一个字没有。 1.确定方案先明白一下概念,以下百科内容: 以太网( Ethernet )是应用最广泛的局域网通讯方式,同时也是一种协议。以太网协议定义了一系列软件和硬件标准,从而将不同的计算机设备连接在一起。以太网( Ethernet )设备组网的基本元素有交换机、路由器、集线器、光纤和普通网线以及以太网协议和通讯规则。以太网中网络数据连接的端口就是以太网接口。以太网接口TCP/IP协议。几种常见的以太网接口类型:SC光纤接口、RJ-45接口、FDDI接口、BNC接口、Console接口。 根据上述百科,我明白到:以太网是局域网的通讯方式,以太网是具有TCP/IP协议,以太网常用接口有RJ45接口。搜索“ESP32 以太网”得到几个方案,大致可以分为两类。1)使用转协议模块,将以太网转为uart、spi等方式通讯。2)使用直连模块,直接使用RMII协议链接以太网。而这些模块一般就是一个PHY芯片,加一个输入网络接口和一排输出排针组成。意识到我好像还不懂PHY是什么,百科内容以下:(TCP/IP协议也不懂,不过下一章再补充,和学习例程时一起补充) PHY(英语:Physical),中文可称之为端口物理层,是一个对OSI模型物理层的共同简称。PHY连接一个数据链路层的设备(MAC)到一个物理媒介,如光纤或铜缆线。(也就是说:单片机设备或电脑设备 - PHY芯片 - 网线)PHY是一个操作OSI模型物理层的设备。一个以太网PHY是一个芯片,可以发送和接收以太网的数据帧(frame)。它通常缺乏NIC(网络接口控制器)芯片所提供的Wake-on-LAN或支持Boot ROM的先进功能。此外,不同于NIC,PHY没有自己的MAC地址。 在找“ESP32 以太网”时,找到一个帖子,属个人论坛的:ESP32 有线接入以太网方法 ,介绍到可以使用LAN8720芯片将ESP32接入以太网。乐鑫也有这种方案的模块:ESP32-Ethernet-Kit V1.2 入门指南,我想着要上就上原生接口,才能学到东西。所以选择某宝找“LAN8720 网络模块 以太网收发器 ETH RMII 接口”,提醒:这模块好像有原版和仿制之分,两者居然差了三倍多的价格。请购买时注意,自行选择。以下是我购买的模块的资料:资料下载:https://pan.baidu.com/s/1T_fFt56sM9qQ4bbrA2oHnA 提取码:6aqz。取自某宝,因为不会失效吧…… 2.准备工作 在选择好方案,模块到手后开始尝试。下载例程,看原理图,查接线。在例程 examples/ethernet/ ,页面下的说明文档README.md中有说明接线方法。特别说明了RMII PHY接线固定,共有6个引脚。SMI 接线不固定,共2个引脚。模块共11个有效引脚,8个信号引脚,2个电源引脚,1个晶振/复位引脚。 在模块原理图中可以得知,该模块上已经焊了一个50MHz的晶振供频率了。这个知识点注意,一会配置工程需要用到。 接好线后,还不可以,在说明文档README.md还有一步,配置工程。这一步操作,在快速入门 第七步:配置,中也有提到,不过之前的例程都不需要配置,所以我之前也没配置过。 在idf终端中,把目录地址切换到工程下,再使用指令:idf.py menuconfig就可以打开菜单界面。配置完毕后工程会生成一个sdkconfig的配置文件。再使用idf.py build指令编译工程后,工程会出现在build/config上生成一个sdkconfig.h的头文件。里面一堆宏定义,然后例程里一些配置的切换就是感觉这些宏定义来的。所以说,官方就是推荐在写工程时尽量使用这些宏定义,这样其他人用我工程时,就可以有可视化的界面来修改工程了。 这次例程中,只需要配置2个界面的内容就可以了。 1) 前2个选项要和我一样,(以太网类型)Ethernet Type - Internal EMAC ,模块选择 LAN8720。 2个SMI引脚我并为改动,使用默认,复位引脚也是。而最后一个是PHY芯片地址设置,根据模块原理图可以得知LAN8720的PHYAD0引脚接了上拉电阻,再根据帖子ESP32 有线接入以太网方法 ,可以知道PHY Address选择1即可。 插入,之前都看到默认事件循环的使用,但是没太在意。现在理理思路,这个使用方法类似创建一个队列? 先创建一个默认事件循环,然后系统生成的所有事件都会进入到这默认事件循环。 虽然这些事件都进入到循环里,但是它们本身也有各自的事件类别。然后指定某类别的事件运行某事件处理程序。然后处理的顺序就按发生的事件顺序执行。处理程序的定义格式好像都是固定的? 找到编程指南里的介绍文档:Default Event Loop。 // 初始化TCP/IP网络接口(在应用程序中只能调用一次) // Initialize TCP/IP network interface (should be called only once in application) ESP_ERROR_CHECK(esp_netif_init()); // 创建在后台运行的默认事件循环 // Create default event loop that running in background ESP_ERROR_CHECK(esp_event_loop_create_default()); esp_netif_config_t cfg = ESP_NETIF_DEFAULT_ETH(); esp_netif_t *eth_netif = esp_netif_new(&cfg); // 设置默认处理程序来处理TCP/IP内容 // Set default handlers to process TCP/IP stuffs ESP_ERROR_CHECK(esp_eth_set_default_handlers(eth_netif)); // 注册用户定义的事件处理程序 // Register user defined event handers ESP_ERROR_CHECK(esp_event_handler_register(ETH_EVENT, ESP_EVENT_ANY_ID, ð_event_handler, NULL)); ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_ETH_GOT_IP, &got_ip_event_handler, NULL)); 以太网 ETH 的事件处理程序 和 IP 的事件处理程序如下。可以看到主要功能其实就是在监视器里打印信息,是调试用的。 /**以太网事件处理程序*/ /** Event handler for Ethernet events */ static void eth_event_handler(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data) { uint8_t mac_addr[6] = {0}; /*我们可以从事件数据中获得以太网驱动程序句柄*/ /* we can get the ethernet driver handle from event data */ esp_eth_handle_t eth_handle = *(esp_eth_handle_t *)event_data; switch (event_id) { case ETHERNET_EVENT_CONNECTED: esp_eth_ioctl(eth_handle, ETH_CMD_G_MAC_ADDR, mac_addr); ESP_LOGI(TAG, "Ethernet Link Up"); ESP_LOGI(TAG, "Ethernet HW Addr %02x:%02x:%02x:%02x:%02x:%02x", mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]); break; case ETHERNET_EVENT_DISCONNECTED: ESP_LOGI(TAG, "Ethernet Link Down"); break; case ETHERNET_EVENT_START: ESP_LOGI(TAG, "Ethernet Started"); break; case ETHERNET_EVENT_STOP: ESP_LOGI(TAG, "Ethernet Stopped"); break; default: break; } } /** IP_EVENT_ETH_GOT_IP的事件处理程序*/ /** Event handler for IP_EVENT_ETH_GOT_IP */ static void got_ip_event_handler(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data) { ip_event_got_ip_t *event = (ip_event_got_ip_t *) event_data; const esp_netif_ip_info_t *ip_info = &event->ip_info; ESP_LOGI(TAG, "Ethernet Got IP Address"); //以太网获取IP地址 ESP_LOGI(TAG, "~~~~~~~~~~~"); ESP_LOGI(TAG, "ETHIP:" IPSTR, IP2STR(&ip_info->ip)); ESP_LOGI(TAG, "ETHMASK:" IPSTR, IP2STR(&ip_info->netmask)); ESP_LOGI(TAG, "ETHGW:" IPSTR, IP2STR(&ip_info->gw)); ESP_LOGI(TAG, "~~~~~~~~~~~"); } 又到了熟悉的结构体配置,不过和上一节wifi配置的一样。参数都被宏定义打包起来了。能配置的只有2个可选引脚的参数。 直接读取然后赋值,丢进配置函数中即可。注意配置了几个函数,返回了各自的句柄(结构体指针),用于配置了下一个。最后启动以太网驱动程序。 eth_phy_config_t phy_config = ETH_PHY_DEFAULT_CONFIG(); phy_config.phy_addr = CONFIG_EXAMPLE_ETH_PHY_ADDR; phy_config.reset_gpio_num = CONFIG_EXAMPLE_ETH_PHY_RST_GPIO; /* 创建一个PHY实例LAN8720 */ esp_eth_phy_t *phy = esp_eth_phy_new_lan8720(&phy_config); eth_mac_config_t mac_config = ETH_MAC_DEFAULT_CONFIG(); mac_config.smi_mdc_gpio_num = CONFIG_EXAMPLE_ETH_MDC_GPIO; mac_config.smi_mdio_gpio_num = CONFIG_EXAMPLE_ETH_MDIO_GPIO; /* 创建ESP32以太网MAC实例 */ esp_eth_mac_t *mac = esp_eth_mac_new_esp32(&mac_config); esp_eth_config_t config = ETH_DEFAULT_CONFIG(mac, phy); esp_eth_handle_t eth_handle = NULL; /* 以太网驱动程序安装 */ ESP_ERROR_CHECK(esp_eth_driver_install(&config, ð_handle)); /*连接TCP/IP协议栈*/ /* attach Ethernet driver to TCP/IP stack */ ESP_ERROR_CHECK(esp_netif_attach(eth_netif, esp_eth_new_netif_glue(eth_handle))); /*启动以太网驱动程序状态机*/ /* start Ethernet driver state machine */ ESP_ERROR_CHECK(esp_eth_start(eth_handle)); 我删除了一些例程中的选择,只剩下我需要的LAN8720部分,所以看起来配置过程还是很简洁的。 二、以太网 到 Wi-Fi AP"路由器"编程指南(英文):Ethernet。 官方例程:ethernet/eth2ap,这个例程的功能是:以太网转wifi。相当于以太网基础例程+wifi的ap例程。 1. 例程解析 因为是旧例程的组合,我直接讲各个组成部分了。下图是实验现象,我先手机连接wifi,再退出wifi。传送门。 以太网驱动程序以面向对象的风格实现。MAC 和 PHY 上的任何操作都应基于其中两个操作的实例。 个人理解,MAC就是指主机接口,6个信号口?PHY就是指通讯芯片,2个片选口?虽然那6个信号接口也是接到PHY芯片上的。 4. 安装驱动程序 传送门。以太网驱动程序还包括事件驱动模型,该模型将为用户空间发送有用且重要的事件。在安装以太网驱动程序之前,我们需要初始化事件循环。 5. 将驱动程序连接到 TCP/IP 堆栈 传送门。到目前为止,我们已经安装了以太网驱动程序。从 OSI(开放系统互连)的角度来看,我们仍处于 2 级(即数据链接层)。我们可以检测上下链接事件,我们可以在用户空间中获取MAC地址,但无法获取IP地址,更不用说发送HTP请求了。ESP-IDF 中使用的 TCP/IP 堆栈称为 LwIP,有关它的更多信息,请参阅LwIP。我才发现在以太网+wifiAP的例程中没有初始化IP的部分。只有第一个以太网有。 6. 以太网驱动程序的误控 传送门。以下功能仅应在安装以太网驱动程序后才能调用。 7. 流控制 传送门。MCU 上的以太网通常限制在网络拥塞期间可以处理的帧数,因为 RAM 大小有限。发送站传输数据的速度可能快于同侪端能够接受的数据。以太网流量控制机制允许接收节点向发送者发出信号,请求暂停传输,直到接收器赶上为止。其背后的魔力是暂停帧,该帧在 IEEE 802.3x 中定义。 四、总结 单单以太网例程没有讲述怎么通讯了,我或许一开始理解错了。以太网好像仅是个连接方式,并不像uart那种直接读取,应该还有个对接的平台。类似iic或spi?总结就是没学会,只是把例程跑起来了。我应该先去把教程前面的内容先学了,现在是因为课设周开始了。我心急跳着学了。 |
今日新闻 |
推荐新闻 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |